'use strict';
// P195、构造函数和new 操作符（运算符/关键字）
// 创建构造函数：设计图
const Person = function (firstName, birthYear) {
    this.firstName = firstName;
    this.birthYear = birthYear;
    // 不要这样添加方法，因为实例化的时候会创建并运行构造函数，当前方法也会被运行，
    // 如果要创建很多实例并且不需要此方法的时候，方法也会被创建
    // this.calcAge = function () {
    //     console.log(2037 - this.birthYear);
    // }
}

// 实例：房子
const may = new Person('May', 1998);
console.log(may); // Person {firstName: 'May', birthYear: 1998}
const linda = new Person('Linda', 2000);
const amy = new Person('Amy', 1995);
console.log(linda, may); // Person {firstName: 'Linda', birthYear: 200} Person {firstName: 'Amy', birthYear: 1995}

const daming = 'daming'
// instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
console.log(may instanceof Person); // true
console.log(daming instanceof Person); // false


// P196、原型
// 可以在构造函数的原型上设置值和方法。
// 所有通过这个构造函数创建的对象会继承，所以他们将获得在此原型属性上定义的所有方法和属性的访问权限。
Person.prototype.calcAge = function () {
    console.log(2037 - this.birthYear);
}
Person.prototype.species = 'woman';

// 任何实例对象总是可以从它的原型访问方法和属性
may.calcAge(); // 39
linda.calcAge(); // 37
console.log(may.species); // woman
console.log(linda.species); // woman

// 每个实例对象都有一个特殊的属性__proto__等于构造函数的原型。
console.log(Person.prototype); // {calcAge: ƒ, constructor: ƒ}
console.log(may.__proto__); // {calcAge: ƒ, constructor: ƒ}
console.log(linda.__proto__ === Person.prototype); // true

// 构造函数的原型是所有构造函数创建的实例的原型，
console.log(Person.prototype.isPrototypeOf(may)); // true
console.log(Person.prototype.isPrototypeOf(linda)); // true

// 构造函数的原型却不是构造函数本身的原型
console.log(Person.prototype.isPrototypeOf(Person)); // false

// 构造函数创建的实例对象（自己）的属性只是那些直接在对象本身上声明的，不包括继承的属性（原型属性）
console.log(may.hasOwnProperty('firstName')); // true
console.log(may.hasOwnProperty('species')); // false


